﻿namespace HCRS.Implementation
{
    using HCRS.Errors;
    using MSXML2;
    using System;
    using System.Configuration;
    using System.Data;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Xml;

    /// <summary>
    /// Fog接口调用
    /// </summary>
    public class FogXml
    {
        /// <summary>
        /// fogUrl路径
        /// </summary>
        private static string xmlgatewayurl = ConfigurationManager.AppSettings["xmlgatewayurl"];
        /// <summary>
        /// fog xml 用户密码
        /// </summary>
        private static string xmlpassword = ConfigurationManager.AppSettings["xmlpassword"];
        /// <summary>
        /// fog xml用户名
        /// </summary>
        private static string xmlusername = ConfigurationManager.AppSettings["xmlusername"];

        /// <summary>
        /// 订单取消 从crs上取消
        /// </summary>
        /// <param name="pid">酒店id</param>
        /// <param name="confnum">订单确认码</param>
        /// <param name="msg">错误信息</param>
        /// <returns></returns>
        public static string cxlresv(ResvCancelInfo resv, out string msg)
        {
            StringBuilder builder = new StringBuilder();
            builder.Append(string.Concat(new object[] { "<crsmessage  PropID='", resv.pid, "'  user='", xmlusername, "'  pass='", xmlpassword, "'  msgtype='cancelresv'  ><reservation><confnum>", resv.confnum, "</confnum><cxlreason>", resv.cxlreason, "</cxlreason></reservation></crsmessage>" }));
            return GetXml(xmlgatewayurl, builder.ToString(), out msg);
        }

        /// <summary>
        /// 订单取消 从crs上取消
        /// </summary>
        /// <param name="pid">酒店id</param>
        /// <param name="confnum">订单确认码</param>
        /// <param name="msg">错误信息</param>
        /// <returns></returns>
        public static string cxlresv(int pid, string confnum, out string msg)
        {
            return cxlresv(new ResvCancelInfo { pid = pid, confnum = confnum }, out msg);
        }

        /// <summary>
        /// 订单取消 从crs上取消
        /// </summary>
        /// <param name="pid">酒店id</param>
        /// <param name="verifycode">外部订单号</param>
        /// <param name="IATA">iata号</param>
        /// <param name="msg">错误信息</param>
        /// <returns></returns>
        public static string cxlresv(int pid, string verifycode, string IATA, out string msg)
        {
            StringBuilder builder = new StringBuilder();
            builder.Append(string.Concat(new object[] { "<crsmessage  PropID='", pid, "'  user='", xmlusername, "'  pass='", xmlpassword, "'  msgtype='cancelresv'  ><reservation><outconfnum>", verifycode, "</outconfnum><miscinfo><IATA>", IATA, "</IATA></miscinfo></reservation></crsmessage>" }));
            return GetXml(xmlgatewayurl, builder.ToString(), out msg);
        }

        /// <summary>
        /// 通过外部订单号查询订单确认号
        /// </summary>
        /// <param name="outconfnum">outconfnum</param>
        /// <param name="pid">酒店PID</param>
        /// <param name="iata">Iata号</param>
        /// <returns>订单确认号</returns>
        public static string GetConfnumByOut(string outconfnum, string pid, string iata)
        {
            string responseText = "";
            string url = ConfigurationManager.AppSettings["getconfnumwebservice"];
            string xmlnamespace = "http://interfacexfire.webservice.syn.fogservice.thayer.com";
            string action = "getResvNumberByOutNumber";
            StringBuilder builder = new StringBuilder();
            builder.Append("<?xml version=\"1.0\" encoding=\"utf-8\"?> ");
            builder.Append("<soap:Envelope  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"> ");
            builder.Append("<soap:Body> ");
            builder.Append("<getResvNumberByOutNumber xmlns=\"" + xmlnamespace + "\"> ");
            builder.Append("<in0>" + xmlusername + "</in0> ");
            builder.Append("<in1>" + xmlpassword + "</in1> ");
            builder.Append("<in2>" + outconfnum + "</in2> ");
            builder.Append("<in3>" + pid + "</in3> ");
            builder.Append("<in4>" + iata + "</in4> ");
            builder.Append("</getResvNumberByOutNumber> ");
            builder.Append("  </soap:Body> ");
            builder.Append("</soap:Envelope> ");
            if (TransferWebService(url, "utf-8", builder.ToString(), xmlnamespace, action, out responseText))
            {
                XmlDataDocument document = new XmlDataDocument();
                document.LoadXml(responseText);
                string innerText = document.GetElementsByTagName("ns1:out")[0].InnerText;
                if ((((innerText != "-10") && (innerText != "0")) && ((innerText != "-1") && (innerText != "-2"))) && (innerText != "-3"))
                {
                    return innerText;
                }
                return "null";
            }
            return "null";
        }

        /// <summary>
        /// 计算转换后的价格
        /// </summary>
        /// <param name="radix">小数点位数</param>
        /// <param name="rule">规则</param>
        /// <param name="rate">汇率</param>
        /// <param name="price"></param>
        /// <returns></returns>
        public static decimal GetExchangeValue(int radix, string rule, double rate, double price)
        {
            if (((price < 0.01) || (rule == "")) || (rate == 0.0))
            {
                return 0M;
            }
            double num = price * rate;
            double num2 = 0.0;
            if ("near".Equals(rule))
            {
                num2 = 0.5;
            }
            else if ("up".Equals(rule))
            {
                num2 = 0.9;
            }
            else if ("down".Equals(rule))
            {
                num2 = 0.0;
            }
            int num3 = (int) Math.Pow(10.0, (double) radix);
            return Convert.ToDecimal((double) (Math.Floor((double) ((num * num3) + num2)) / ((double) num3)));
        }

        /// <summary>
        /// 转换价格
        /// </summary>
        /// <param name="ExchangeRateTableName">数据库汇率表名</param>
        /// <param name="date">取汇率日期</param>
        /// <param name="price">价格</param>
        /// <param name="fromcode">从货币</param>
        /// <param name="tocode">转货币</param>
        /// <returns></returns>
        public static decimal GetHubs1ExchangeValue(string ExchangeRateTableName, DateTime date, double price, string fromcode, string tocode)
        {
            if (ExchangeRateTableName == "")
            {
                ExchangeRateTableName = "ExchangeRate";
            }
            if (fromcode == tocode)
            {
                return Convert.ToDecimal(price);
            }
            fromcode = fromcode.ToUpper();
            tocode = tocode.ToUpper();
            string str = date.ToString("yyyyMM");
            DataTable table = CommonDataAccess.GetTable(" select * from (select 0 as o, tocode,fromcode,rate,radixpoint,roundrule  from " + ExchangeRateTableName + " where fromcode='" + fromcode + "' and tocode='" + tocode + "' and   months='" + str + "' union select 1 as o, tocode,fromcode,rate,radixpoint,roundrule  from " + ExchangeRateTableName + " where tocode='" + fromcode + "' and fromcode='" + tocode + "' and   months='" + str + "')a order by o", "rate");
            if ((table != null) && (table.Rows.Count > 0))
            {
                int num = Convert.ToInt32(table.Rows[0]["o"]);
                int radix = Convert.ToInt32(table.Rows[0]["radixpoint"]);
                string str3 = table.Rows[0]["roundrule"].ToString();
                double rate = Convert.ToDouble(table.Rows[0]["rate"]);
                if (num == 0)
                {
                    return GetExchangeValue(radix, str3.ToLower().Trim(), rate, price);
                }
                return GetExchangeValue(radix, str3.ToLower().Trim(), 1.0 / rate, price);
            }
            return 0M;
        }

        internal static string getonlineratemap(GetRateInfo info, out string msg)
        {
            if (info.iata == "")
            {
                info.iata = "899999";
            }
            if ("0,1,2".IndexOf(info.filter) < 0)
            {
                info.filter = "2";
            }
            StringBuilder builder = new StringBuilder();
            string str = (info.language == 0) ? "zh" : "en";
            builder.Append(string.Concat(new object[] { "<crsmessage  PropID='", info.pid, "'  user='", xmlusername, "'  pass='", xmlpassword, "'  msgtype='getonlineratemap' language='", str, "' nolog='1'><options cascade='true'/>" }));
            builder.Append("<iata>" + info.iata + "</iata>");
            for (int i = 0; i < info.ratecodes.Length; i++)
            {
                if ((info.roomcodes != null) && (info.roomcodes.Length > 0))
                {
                    for (int j = 0; j < info.roomcodes.Length; j++)
                    {
                        builder.Append(string.Concat(new object[] { 
                            "<staydetail><channel>Website</channel><date>", info.checkin, "</date><rateclass>", info.ratecodes[i], "</rateclass><roomtype>", info.roomcodes[j], "</roomtype><nights>", info.nights, "</nights><rooms>", info.rooms, "</rooms><adults>", info.adults, "</adults><children>", info.children, "</children>", (info.currencycode.Length == 0) ? "" : ("<currencycode>" + info.currencycode + "</currencycode>"), 
                            "<filter>", info.filter, "</filter></staydetail>"
                         }));
                    }
                }
                else
                {
                    builder.Append(string.Concat(new object[] { 
                        "<staydetail><channel>Website</channel><date>", info.checkin, "</date><rateclass>", info.ratecodes[i], "</rateclass><nights>", info.nights, "</nights><rooms>", info.rooms, "</rooms><adults>", info.adults, "</adults><children>", info.children, "</children>", (info.currencycode.Length == 0) ? "" : ("<currencycode>" + info.currencycode + "</currencycode>"), "<filter>", info.filter, 
                        "</filter></staydetail>"
                     }));
                }
            }
            builder.Append("</crsmessage>");
            return GetXml(xmlgatewayurl, builder.ToString(), out msg);
        }

        /// <summary>
        /// 查询酒店价格
        /// </summary>
        /// <param name="actionname">getexratemap</param>
        /// <param name="resv">查询条件对象</param>
        /// <param name="msg">返回信息</param>
        /// <returns></returns>
        public static string getratemap(string actionname, GetRateInfo resv, out string msg)
        {
            if (resv.iata == "")
            {
                resv.iata = "899999";
            }
            if ("0,1,2".IndexOf(resv.filter) < 0)
            {
                resv.filter = "2";
            }
            StringBuilder builder = new StringBuilder();
            string str = (resv.language == 0) ? "zh" : "en";
            builder.Append(string.Concat(new object[] { "<crsmessage  PropID='", resv.pid, "'  user='", xmlusername, "'  pass='", xmlpassword, "'  msgtype='", actionname, "' language='", str, "' nolog='1'><options cascade='true'/>" }));
            builder.Append("<iata>" + resv.iata + "</iata>");
            for (int i = 0; i < resv.ratecodes.Length; i++)
            {
                if ((resv.roomcodes != null) && (resv.roomcodes.Length > 0))
                {
                    for (int j = 0; j < resv.roomcodes.Length; j++)
                    {
                        builder.Append(string.Concat(new object[] { 
                            "<staydetail><channel>Website</channel><date>", resv.checkin, "</date><ratecode>", resv.ratecodes[i], "</ratecode><roomcode>", resv.roomcodes[j], "</roomcode><nights>", resv.nights, "</nights><rooms>", resv.rooms, "</rooms><adults>", resv.adults, "</adults><children>", resv.children, "</children>", (resv.currencycode.Length == 0) ? "" : ("<currencycode>" + resv.currencycode + "</currencycode>"), 
                            "<filter>", resv.filter, "</filter></staydetail>"
                         }));
                    }
                }
                else
                {
                    builder.Append(string.Concat(new object[] { 
                        "<staydetail><channel>Website</channel><date>", resv.checkin, "</date><ratecode>", resv.ratecodes[i], "</ratecode><nights>", resv.nights, "</nights><rooms>", resv.rooms, "</rooms><adults>", resv.adults, "</adults><children>", resv.children, "</children>", (resv.currencycode.Length == 0) ? "" : ("<currencycode>" + resv.currencycode + "</currencycode>"), "<filter>", resv.filter, 
                        "</filter></staydetail>"
                     }));
                }
            }
            builder.Append("</crsmessage>");
            return GetXml(xmlgatewayurl, builder.ToString(), out msg);
        }

        /// <summary>
        /// 查询酒店房型房价
        /// </summary>
        /// <param name="actionname">接口名称</param>
        /// <param name="iata">iata号</param>
        /// <param name="pid">酒店PID</param>
        /// <param name="roomcodes">房型代码数组</param>
        /// <param name="ratecodes">价格代码数组</param>
        /// <param name="checkin">入住时间</param>
        /// <param name="nights">过夜天数</param>
        /// <param name="adults">成人数量</param>
        /// <param name="children">儿童数量</param>
        /// <param name="rooms">房间数量</param>
        /// <param name="language">语言（0中文，1英文）</param>
        /// <param name="filter">过滤(0查全部,1不包括B的,2不包括B，并且时间上是连续的)</param>
        /// <param name="currencycode">货币代码(CNY,USD,HKD)getexratemap有效</param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public static string getratemap(string actionname, string iata, int pid, string[] roomcodes, string[] ratecodes, string checkin, int nights, int adults, int children, int rooms, int language, string filter, string currencycode, out string msg)
        {
            if (iata == "")
            {
                iata = "899999";
            }
            if ("0,1,2".IndexOf(filter) < 0)
            {
                filter = "2";
            }
            StringBuilder builder = new StringBuilder();
            string str = (language == 0) ? "zh" : "en";
            builder.Append(string.Concat(new object[] { "<crsmessage  PropID='", pid, "'  user='", xmlusername, "'  pass='", xmlpassword, "'  msgtype='", actionname, "' language='", str, "' nolog='1'><options cascade='true'/>" }));
            builder.Append("<iata>" + iata + "</iata>");
            for (int i = 0; i < ratecodes.Length; i++)
            {
                if ((roomcodes != null) && (roomcodes.Length > 0))
                {
                    for (int j = 0; j < roomcodes.Length; j++)
                    {
                        builder.Append(string.Concat(new object[] { 
                            "<staydetail><channel>Website</channel><date>", checkin, "</date><rateclass>", ratecodes[i], "</rateclass><roomtype>", roomcodes[j], "</roomtype><nights>", nights, "</nights><rooms>", rooms, "</rooms><adults>", adults, "</adults><children>", children, "</children>", (currencycode.Length > 0) ? "" : ("<currencycode>" + currencycode + "</currencycode>"), 
                            "<filter>", filter, "</filter></staydetail>"
                         }));
                    }
                }
                else
                {
                    builder.Append(string.Concat(new object[] { 
                        "<staydetail><channel>Website</channel><date>", checkin, "</date><rateclass>", ratecodes[i], "</rateclass><nights>", nights, "</nights><rooms>", rooms, "</rooms><adults>", adults, "</adults><children>", children, "</children>", (currencycode.Length > 0) ? "" : ("<currencycode>" + currencycode + "</currencycode>"), "<filter>", filter, 
                        "</filter></staydetail>"
                     }));
                }
            }
            builder.Append("</crsmessage>");
            return GetXml(xmlgatewayurl, builder.ToString(), out msg);
        }

        /// <summary>
        /// 获取xml接口文件字符串
        /// </summary>
        /// <param name="url">调用url</param>
        /// <param name="xml">xml文档</param>
        /// <param name="msg">输出信息</param>
        /// <returns></returns>
        public static string GetXml(string url, string xml, out string msg)
        {
            ServerXMLHTTP rxmlhttp = new ServerXMLHTTPClass();
            msg = "";
            string str = "";
            try
            {
                rxmlhttp.setTimeouts(0x4e20, 0x4e20, 0x4e20, 0x9c40);
                rxmlhttp.open("POST", url, false, null, null);
                rxmlhttp.setRequestHeader("Content-Type", "text/xml;charset=utf-8");
                rxmlhttp.send(xml);
                if (rxmlhttp.readyState == 4)
                {
                    if (rxmlhttp.responseText.Trim() != "")
                    {
                        return rxmlhttp.responseText.Replace("\n", "").Replace(@"\", "").Replace("\r", "");
                    }
                    msg = "ErrEmpty";
                    WebError.SendErrorEmail(new Exception("[send]" + xml + " <br/>[response]<br/> " + rxmlhttp.responseText));
                }
                return str;
            }
            catch (Exception exception)
            {
                msg = "ErrConnect";
                WebError.SendErrorEmail(exception);
            }
            finally
            {
                rxmlhttp.abort();
            }
            return str;
        }

        /// <summary>
        /// 订单修改 
        /// </summary>
        /// <param name="resv">修改信息</param>      
        /// <param name="msg">错误信息</param>
        /// <returns></returns>
        public static string modresv(ResvModifyInfo resv, out string msg)
        {
            int num;
            StringBuilder builder = new StringBuilder();
            StringBuilder builder2 = new StringBuilder();
            StringBuilder builder3 = new StringBuilder();
            builder3.Append("<specialrequirement>");
            if ((resv.specialrequirement != null) && (resv.specialrequirement.Length > 0))
            {
                for (num = 0; num < resv.specialrequirement.Length; num++)
                {
                    builder2.Append("<reqcode>");
                    builder2.Append(resv.specialrequirement[num]);
                    builder2.Append("</reqcode>");
                }
            }
            builder3.Append("</specialrequirement>");
            builder2.Append("<otherguest>");
            if ((resv.otherguest != null) && (resv.otherguest.Length > 0))
            {
                for (num = 0; num < resv.otherguest.Length; num++)
                {
                    builder2.Append("<guestname>");
                    builder2.Append(resv.otherguest[num]);
                    builder2.Append("</guestname>");
                }
            }
            builder2.Append("</otherguest>");
            builder.Append(string.Concat(new object[] { 
                "<crsmessage  PropID='", resv.pid, "'  user='", xmlusername, "'  pass='", xmlpassword, "'  msgtype='modresv'  nolog='1'><options cascade='true'/><reservation><confnum>", resv.confnum, "</confnum><guestinfo><lastname>", resv.lastname, "</lastname><firstname>", resv.firstname, "</firstname>", builder2.ToString(), "<title></title><holdTime>", resv.holdtime, 
                "</holdTime><street1>", resv.guestaddressline1, "</street1><phone>", resv.guestphone, "</phone><mobile>", resv.mobile, "</mobile><email>", resv.guestemail, "</email></guestinfo>", builder3.ToString(), "<remarks><remark><![CDATA[", resv.remark, "]]></remark><remark>[Modify from ", resv.from, "]</remark></remarks></reservation></crsmessage>"
             }));
            return GetXml(xmlgatewayurl, builder.ToString(), out msg);
        }

        /// <summary>
        /// 订单修改 
        /// </summary>
        /// <param name="pid">酒店id</param>
        /// <param name="confnum">确认码</param>
        /// <param name="firstname">姓</param>
        /// <param name="lastname">名</param>
        /// <param name="guestaddressline1">客人地址</param>
        /// <param name="guestphone">客人电话</param>
        /// <param name="guestemail">客人电子邮件</param>
        /// <param name="remark">备注</param>
        /// <param name="from">订单来源</param>
        /// <param name="msg">错误信息</param>
        /// <returns></returns>
        public static string modresv(int pid, string confnum, string firstname, string lastname, string guestaddressline1, string guestphone, string guestemail, string remark, string from, out string msg)
        {
            return modresv(new ResvModifyInfo { pid = pid, confnum = confnum, firstname = firstname, lastname = lastname, guestaddressline1 = guestaddressline1, guestphone = guestphone, guestemail = guestemail, remark = remark, from = from }, out msg);
        }

        /// <summary>
        /// 酒店新预订
        /// </summary>
        /// <param name="actionname">fog方法参数</param>
        /// <param name="resv">订单信息</param>
        /// <param name="msg">out类型的错误信息</param>
        /// <returns></returns>
        public static string newresv(string actionname, ResvInfo resv, out string msg)
        {
            int num;
            StringBuilder builder = new StringBuilder();
            StringBuilder builder2 = new StringBuilder();
            StringBuilder builder3 = new StringBuilder();
            builder3.Append("<specialrequirement>");
            if ((resv.specialrequirement != null) && (resv.specialrequirement.Length > 0))
            {
                for (num = 0; num < resv.specialrequirement.Length; num++)
                {
                    builder2.Append("<reqcode>");
                    builder2.Append(resv.specialrequirement[num]);
                    builder2.Append("</reqcode>");
                }
            }
            builder3.Append("</specialrequirement>");
            StringBuilder builder4 = new StringBuilder();
            if (((resv.dates != null) && (resv.prices != null)) && (resv.dates.Length == resv.prices.Length))
            {
                builder4.Append("<bookedrates>");
                for (num = 0; num < resv.dates.Length; num++)
                {
                    builder4.Append("<bookedrate>");
                    builder4.Append("<date>" + resv.dates[num] + "</date>");
                    builder4.Append("<rate>" + resv.prices[num] + "</rate>");
                    if (resv.currencycodes != null)
                    {
                        builder4.Append("<currencycode>" + resv.currencycodes[num] + "</currencycode>");
                    }
                    builder4.Append("</bookedrate>");
                }
                builder4.Append("</bookedrates>");
            }
            builder2.Append("<otherguest>");
            if ((resv.otherguest != null) && (resv.otherguest.Length > 0))
            {
                for (num = 0; num < resv.otherguest.Length; num++)
                {
                    builder2.Append("<guestname>");
                    builder2.Append(resv.otherguest[num]);
                    builder2.Append("</guestname>");
                }
            }
            builder2.Append("</otherguest>");
            builder.Append(string.Concat(new object[] { "<crsmessage  PropID='", resv.pid, "'  user='", xmlusername, "'  pass='", xmlpassword, "'  msgtype='", actionname, "'  nolog='1'><options cascade='true'/>" }));
            builder.Append(string.Concat(new object[] { 
                "<reservation><outconfnum>", resv.verifycode, "</outconfnum><staydetail><date>", resv.checkin, "</date><rateclass>", resv.ratecode, "</rateclass><roomtype>", resv.roomcode, "</roomtype><nights>", resv.nights, "</nights><rooms>", resv.rooms, "</rooms><adults>", resv.adults, "</adults><children>", resv.children, 
                "</children></staydetail><guestinfo><firstname>", resv.firstname, "</firstname>", builder2.ToString(), "<lastname>", resv.lastname, "</lastname><title></title><street1>", resv.guestaddressline1, "</street1><city>", resv.guestcity, "</city><state>", resv.gueststatecn, "</state><postcode>", resv.guestzip, "</postcode><country>", resv.guestcountry, 
                "</country><holdTime>", resv.holdtime, "</holdTime><phone>", resv.guestphone, "</phone><mobile>", resv.mobile, "</mobile><email>", resv.guestemail, "</email></guestinfo>", builder3.ToString(), "", resv.specialxml, "", builder4, "<ccinfo><ccname>", resv.ccname, 
                "</ccname><cctype>", resv.cctype, "</cctype><ccnum>", resv.ccnumber, "</ccnum><ccexp>", resv.ccexpmonth, "/", resv.ccexpyear, "</ccexp><cvv>", resv.cvv, "</cvv></ccinfo><remarks><remark><![CDATA[", resv.remark, "]]></remark><remark>[Booking from ", resv.from, "]</remark></remarks><isassure>", resv.assuranceCode, "</isassure><miscinfo><IATA>", resv.iata, 
                "</IATA><freqguestID>", resv.frequentguestid, "</freqguestID><subsource>", resv.subsource, "</subsource></miscinfo></reservation>"
             }));
            builder.Append("</crsmessage>");
            return GetXml(xmlgatewayurl, builder.ToString(), out msg);
        }

        /// <summary>
        /// 酒店新预订
        /// </summary>
        /// <param name="actionname">fog方法参数</param>
        /// <param name="verifycode">订单唯一标示号</param>
        /// <param name="roomcode">房型代码</param>
        /// <param name="ratecode">价格代码</param>
        /// <param name="checkin">入住日期</param>
        /// <param name="pid">酒店pid</param>
        /// <param name="nights">房夜数</param>
        /// <param name="adults">成人数</param>
        /// <param name="children">儿童数</param>
        /// <param name="rooms">房间数</param>
        /// <param name="firstname">姓</param>
        /// <param name="lastname">名</param>
        /// <param name="guestaddressline1">客人地址</param>
        /// <param name="guestcity">客人城市</param>
        /// <param name="gueststatecn">客人所在省州</param>
        /// <param name="guestzip">客人邮编</param>
        /// <param name="guestcountry">客人所在国家</param>
        /// <param name="guestphone">电话</param>
        /// <param name="guestemail">电子邮件</param>
        /// <param name="ccname">卡主姓名</param>
        /// <param name="cctype">卡类型</param>
        /// <param name="ccnumber">卡号</param>
        /// <param name="ccexpyear">过期年份</param>
        /// <param name="ccexpmonth">过期月份</param>
        /// <param name="remark">备注</param>
        /// <param name="from">订单来源</param>
        /// <param name="iata">公司iata</param>
        /// <param name="frequentguestid">常客id</param>
        /// <param name="subsource"></param>
        /// <param name="specialxml">特殊xml节点字符串（扩展）</param>
        /// <param name="msg">out类型的错误信息</param>
        /// <returns></returns>
        public static string newresv(string actionname, string verifycode, string roomcode, string ratecode, string checkin, int pid, int nights, int adults, int children, int rooms, string firstname, string lastname, string guestaddressline1, string guestcity, string gueststatecn, string guestzip, string guestcountry, string guestphone, string guestemail, string ccname, string cctype, string ccnumber, string ccexpyear, string ccexpmonth, string remark, string from, string iata, string frequentguestid, string subsource, string specialxml, string[] prices, string[] dates, string[] currencycodes, out string msg)
        {
            ResvInfo resv = new ResvInfo {
                verifycode = verifycode,
                roomcode = roomcode,
                ratecode = ratecode,
                checkin = checkin,
                pid = pid,
                nights = nights,
                adults = adults,
                children = children,
                rooms = rooms,
                firstname = firstname,
                lastname = lastname,
                guestaddressline1 = guestaddressline1,
                guestcity = guestcity,
                gueststatecn = gueststatecn,
                guestzip = guestzip,
                guestcountry = guestcountry,
                guestphone = guestphone,
                guestemail = guestemail,
                ccname = ccname,
                cctype = cctype,
                ccnumber = ccnumber,
                ccexpyear = ccexpyear,
                ccexpmonth = ccexpmonth,
                remark = remark,
                from = from,
                iata = iata,
                frequentguestid = frequentguestid,
                subsource = subsource,
                specialxml = specialxml,
                prices = prices,
                dates = dates,
                currencycodes = currencycodes
            };
            return newresv(actionname, resv, out msg);
        }

        /// <summary>
        /// 保存Hubs1汇率（定期调用保存至汇率表）
        /// </summary>
        /// <param name="year">年份</param>
        /// <param name="ExchangeRateTable">汇率表名</param>
        /// <param name="msg">输出信息</param>
        /// <returns></returns>
        public static bool SaveExchangeRate_Hubs1(string year, string ExchangeRateTableName, out string msg)
        {
            msg = "";
            try
            {
                if (ExchangeRateTableName == "")
                {
                    ExchangeRateTableName = "ExchangeRate";
                }
                string url = ConfigurationManager.AppSettings["exchangeratevaluewebservice"];
                string xml = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:crs=\"http://crs.webservice.fogservice.thayer.com/\">    <soapenv:Header/>    <soapenv:Body>       <crs:findExchangeRateAndValue>          <arg0>" + year + "</arg0>       </crs:findExchangeRateAndValue>    </soapenv:Body> </soapenv:Envelope> ";
                xml = GetXml(url, xml, out msg);
                XmlDataDocument document = new XmlDataDocument();
                document.LoadXml(xml);
                XmlNode documentElement = document.DocumentElement;
                XmlNamespaceManager nsmgr = new XmlNamespaceManager(document.NameTable);
                nsmgr.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
                nsmgr.AddNamespace("ns2", "http://crs.webservice.fogservice.thayer.com/");
                XmlNodeList list = documentElement.SelectNodes("soap:Body//ns2:findExchangeRateAndValueResponse//return", nsmgr);
                StringBuilder builder = new StringBuilder();
                builder.Append("create table #ExchangeRate (");
                builder.Append("months               varchar(10)          not null,");
                builder.Append("tocode               nvarchar(5)          not null,");
                builder.Append("fromcode             nvarchar(5)          not null,");
                builder.Append("rate                 decimal(38,12)       not null,");
                builder.Append("radixPoint           int                  not null,");
                builder.Append("roundRule            nvarchar(20)         not null ");
                builder.Append(");");
                foreach (XmlNode node2 in list)
                {
                    XmlNodeList list2 = node2.SelectNodes("exchangeRateValue");
                    if (list2.Count >= 1)
                    {
                        string str3 = node2.SelectSingleNode("currencyCode_foreign").InnerText.Trim();
                        string str4 = node2.SelectSingleNode("currencyCode_local").InnerText.Trim();
                        int num = Convert.ToInt32(node2.SelectSingleNode("radixPoint").InnerText);
                        string str5 = node2.SelectSingleNode("roundRule").InnerText.Trim();
                        foreach (XmlNode node3 in list2)
                        {
                            string str6 = node3.SelectSingleNode("month").InnerText.Trim();
                            decimal num2 = Convert.ToDecimal(node3.SelectSingleNode("value").InnerText.Trim());
                            builder.Append(string.Concat(new object[] { "insert #ExchangeRate select '", str6, "','", str3, "','", str4, "',", num2, ",", num, ",'", str5, "';" }));
                        }
                    }
                }
                builder.Append("update " + ExchangeRateTableName + " ");
                builder.Append("set rate=b.rate,radixPoint=b.radixPoint,roundRule=b.roundRule ");
                builder.Append("from #ExchangeRate b where  ");
                builder.Append("" + ExchangeRateTableName + ".months=b.months  ");
                builder.Append("and " + ExchangeRateTableName + ".tocode=b.tocode  ");
                builder.Append("and " + ExchangeRateTableName + ".fromcode=b.fromcode; \n ");
                builder.Append("delete  #ExchangeRate from  " + ExchangeRateTableName + " b where ");
                builder.Append(" #ExchangeRate.months=b.months  ");
                builder.Append("and #ExchangeRate.tocode=b.tocode  ");
                builder.Append("and #ExchangeRate.fromcode=b.fromcode;  ");
                builder.Append("insert into " + ExchangeRateTableName);
                builder.Append("(months,tocode,fromcode,rate,radixPoint,roundRule)");
                builder.Append("select  *  from #ExchangeRate  ;\n");
                builder.Append("drop table #ExchangeRate;");
                return CommonDataAccess.ExecuteTransaction(builder.ToString(), out msg);
            }
            catch (Exception exception)
            {
                msg = exception.Message;
                WebError.SendErrorEmail(exception);
                return false;
            }
        }

        /// <summary>
        /// WebService调用
        /// </summary>
        /// <param name="url">Url</param>
        /// <param name="encode">字符编码</param>
        /// <param name="strRequest">PostXml soap:Envelope</param>
        /// <param name="xmlnamespace">xml命名空间</param>
        /// <param name="action">调用方法</param>
        /// <param name="responseText">返回xml文档</param>
        /// <returns></returns>
        public static bool TransferWebService(string url, string encode, string strRequest, string xmlnamespace, string action, out string responseText)
        {
            ServerXMLHTTP rxmlhttp = new ServerXMLHTTPClass();
            try
            {
                rxmlhttp.open("POST", url, false, null, null);
                rxmlhttp.setRequestHeader("Content-Type", "text/xml; charset=" + encode + "");
                rxmlhttp.setRequestHeader("SOAPAction", xmlnamespace + "/" + action);
                rxmlhttp.send(strRequest);
                if (rxmlhttp.readyState != 4)
                {
                    throw new Exception("未响应，超时！");
                }
                responseText = rxmlhttp.responseText;
                return true;
            }
            catch (Exception exception)
            {
                responseText = exception.Message;
                return false;
            }
        }
    }
}

